package common

import (
	"fmt"
	"github.com/piaohao/godis"
	"github.com/samuel/go-zookeeper/zk"
	"time"
)

//分布式锁
type JobRedisDistributeLock struct {
	redisLock  *godis.Locker
	WorkerLock *godis.Lock
	jobName    string //不同的任务不同的锁
	lockPath   string
	isJobLock  bool
	isInitial  bool
}

//创建分布式锁
func InitDistributeLock(jobName, lockpath string, lease time.Duration) (jobRDLock *JobRedisDistributeLock) {
	redisLock := godis.NewLocker(&godis.Option{
		Host: "192.168.147.133",
		Port: 6379,
		Db:   0,
	}, &godis.LockOption{
		Timeout: lease,
	})

	jobRDLock = &JobRedisDistributeLock{
		redisLock:  redisLock,
		WorkerLock: nil,
		lockPath:   lockpath,
		isJobLock:  false,
	}
	return

}

func (jobLock *JobRedisDistributeLock) TryLock(jobName string) (err error) {
	jobLock.WorkerLock, err = jobLock.redisLock.TryLock(jobLock.lockPath + jobName)

	if err != nil {
		//fmt.Println("tryLock失败：", err.Error())
		goto FAILED
	}
	jobLock.isJobLock = true
	return
FAILED:
	err = ERR_LOCK_ALREAD_REQIURED
	return
}

func (jobLock *JobRedisDistributeLock) Unlock() {
	if jobLock.isJobLock {
		//解锁
		jobLock.redisLock.UnLock(jobLock.WorkerLock)
		jobLock.isJobLock = false
	}
}

type JobZKDistributeLock struct {
	conn       *zk.Conn
	WorkerLock *zk.Lock
	jobName    string //不同的任务不同的锁
	lockPath   string
	isJobLock  bool
	isInitial  bool
}

//创建分布式锁
func InitZKDistributeLock(con *zk.Conn, jobName, lockpath string, lease time.Duration) (jobZKLock *JobZKDistributeLock) {
	WorkerLock := zk.NewLock(con, lockpath, zk.WorldACL(zk.PermAll))
	jobZKLock = &JobZKDistributeLock{
		conn:       con,
		jobName:    jobName,
		lockPath:   lockpath,
		WorkerLock: WorkerLock,
	}
	return

}

func (jobLock *JobZKDistributeLock) TryLock() (err error) {
	err = jobLock.WorkerLock.Lock()

	if err != nil {
		fmt.Println("tryLock失败：", err.Error())
		goto FAILED
	}
	jobLock.isJobLock = true
	return
FAILED:
	err = ERR_LOCK_ALREAD_REQIURED
	return
}

func (jobLock *JobZKDistributeLock) Unlock() {
	if jobLock.isJobLock {
		//解锁
		jobLock.WorkerLock.Unlock()
		jobLock.isJobLock = false
	}
}
